﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using GGJ_DKG.Objects;
using GGJ_DKG.Menu;
using GGJ_DKG.Managers;
namespace GGJ_DKG.Objects
{
    class SceneryManager
    {
        #region Variables

        #region Public
        #endregion

        #region Objects
        Object2D backGround0;
        Object2D backGround1;
        Fish fish;
        #endregion

        #region Textures
        Texture2D edgeAlgea;
        Texture2D edgeRadio;
        Texture2D centerAlgea;
        Texture2D centerRadio;
        Texture2D airBubble;
        Texture2D fish0;
        Texture2D fish1;
        Texture2D fish2;
        Texture2D fish3;
        #endregion

        #region Lists
        List<float> nextFishMeterList;
        List<float> nextFishMeterList2;
        List<float> nextMeterListEdge;
        List<float> nextMeterListCenter;
        List<Fish> FishList;
        List<Fish> FishList2;
        List<Object2D> objListEdge;
        List<Object2D> objListCenter;
        #endregion

        #region Misc
        bool canMoveScene;
        string lastObjCenter;
        string lastObjEdge;

        int masterIndexCenter;
        int masterIndexEdge;
        int masterIndexFish;
        int masterIndexFish2;
        #endregion
        #endregion

        public SceneryManager(ContentManager Content, GraphicsDeviceManager graphics)
        {

            #region Scenery
            centerAlgea = Content.Load<Texture2D>("Scenario/base_alga_meio");
            edgeAlgea = Content.Load<Texture2D>("Scenario/base_alga_right");
            centerRadio = Content.Load<Texture2D>("Scenario/Radiativo_Meio");
            edgeRadio = Content.Load<Texture2D>("Scenario/Radiativo_Left");
            airBubble = Content.Load<Texture2D>("Scenario/Checkpoint");
            fish0 = Content.Load<Texture2D>("SpritesPlayer/pexe3_60x32");
            fish1 = Content.Load<Texture2D>("SpritesPlayer/pexe2_70x67");
            fish2 = Content.Load<Texture2D>("SpritesPlayer/pexe1_115x102");
            fish3 = Content.Load<Texture2D>("SpritesPlayer/pexe4_200x140");
            #endregion

            #region Management
            Random rand = new Random();


            masterIndexEdge = -1;
            nextMeterListEdge = new List<float>();
            objListEdge = new List<Object2D>();
            RandEdge(rand);


            masterIndexCenter = -1;
            nextMeterListCenter = new List<float>();
            objListCenter = new List<Object2D>();
            RandCenter(rand);

            masterIndexFish = -1;
            nextFishMeterList = new List<float>();
            FishList = new List<Fish>();
            RandFish(rand);

            masterIndexFish2 = -1;
            nextFishMeterList2 = new List<float>();
            FishList2 = new List<Fish>();
            RandFish2(rand);
            #endregion

            #region Background
            backGround0 = new Object2D(Content.Load<Texture2D>("Scenario/BG_800_600_PB"));
            backGround0.Position = new Vector2(graphics.PreferredBackBufferWidth / 2,
                graphics.PreferredBackBufferHeight / 2);
            backGround0.Rotation = 0;
            backGround0.Alpha = 2.5f;
            backGround0.ScaleVector = new Vector2(1f, 1.004f);

            backGround1 = new Object2D(Content.Load<Texture2D>("Scenario/BG_800_600_PB"));
            backGround1.Position = new Vector2(graphics.PreferredBackBufferWidth / 2,
                backGround0.Position.Y + backGround1.Texture.Height);
            backGround1.Rotation = 0;
            backGround1.Alpha = 2.5f;
            backGround1.ScaleVector = new Vector2(1f, 1.004f);
            #endregion

        }

        public void Update(GameTime gameTime)
        {
            #region Management
            Random rand = new Random();
            if (Math.Truncate(Game1.Self.meters) == 0)
            {
                canMoveScene = false;
            }
            else
            {
                canMoveScene = true;
            }
            RandEdge(rand);
            RandCenter(rand);
            RandFish(rand);
            RandFish2(rand);
            #endregion

            #region Background
            if (Game1.Self.playerRotation >= MathHelper.ToRadians(90))
            {
                if (backGround0.Position.Y < 0 - (backGround0.Texture.Height / 2))
                {
                    backGround0.Position = new Vector2(backGround0.Position.X,
                        Game1.Self.Window.ClientBounds.Height + backGround0.Texture.Height / 2);
                }
                if (backGround1.Position.Y < 0 - (backGround1.Texture.Height / 2))
                {
                    backGround1.Position = new Vector2(backGround1.Position.X,
                        Game1.Self.Window.ClientBounds.Height + backGround1.Texture.Height / 2);
                }
                backGround0.Position -= new Vector2(0, 1.225f);
                backGround1.Position -= new Vector2(0, 1.225f);
            }
            else if (canMoveScene)
            {
                if (backGround0.Position.Y > Game1.Self.Window.ClientBounds.Height + (backGround1.Texture.Height / 2))
                {
                    backGround0.Position = new Vector2(backGround0.Position.X,
                        0 - backGround0.Texture.Height / 2);
                }
                else if (backGround1.Position.Y > Game1.Self.Window.ClientBounds.Height + (backGround1.Texture.Height / 2))
                {
                    backGround1.Position = new Vector2(backGround1.Position.X, 0 - backGround1.Texture.Height / 2);
                }
                backGround0.Position += new Vector2(0, 3.5f);
                backGround1.Position += new Vector2(0, 3.5f);
            }
            #endregion

            #region Scenery

            if (Game1.Self.playerRotation >= MathHelper.ToRadians(90))
            {
                #region Center
                if (objListCenter[masterIndexCenter] != null)
                    objListCenter[masterIndexCenter].Position -= new Vector2(0, 1.225f);
                #region HitTest
                if (objListCenter[masterIndexCenter] is AirBubble)
                {
                    if (objListCenter[masterIndexCenter].hitTestObject(Game1.Self.playerRect))
                    {
                        Game1.Self.fillingAir = true;
                    }
                    else
                    {
                        Game1.Self.fillingAir = false;
                    }
                }
                else
                {
                    if (objListCenter[masterIndexCenter].hitTestObject(Game1.Self.playerRect))
                    {
                        Level.playerDown = false;
                    }
                    else
                    {
                        Level.playerDown = true;
                    }
                }
                #endregion

                #endregion

                #region Fish
                if (FishList[masterIndexFish] != null)
                {
                    FishList[masterIndexFish].Update(gameTime);
                    FishList[masterIndexFish].Position -= new Vector2(0, 1.225f);
                }
                if (FishList2[masterIndexFish2] != null)
                {
                    FishList2[masterIndexFish2].Update(gameTime);
                    FishList2[masterIndexFish2].Position -= new Vector2(0, 1.225f);
                }
                #endregion

                #region Edge
                if (objListEdge[masterIndexEdge] != null)
                    objListEdge[masterIndexEdge].Position -= new Vector2(0, 1.225f);

                #endregion
            }
            else if (canMoveScene)
            {
                #region Center
                if (masterIndexCenter != -1 &&
                    objListCenter[masterIndexCenter] != null)
                    objListCenter[masterIndexCenter].Position += new Vector2(0, 3.5f);
                #endregion

                #region Fish
                if (masterIndexFish != -1 &&
                    FishList[masterIndexFish] != null)
                {
                    FishList[masterIndexFish].Update(gameTime);
                    FishList[masterIndexFish].Position += new Vector2(0, 3.5f);
                }
                if (masterIndexFish2 != -1 &&
                    FishList2[masterIndexFish2] != null)
                {
                    FishList2[masterIndexFish2].Update(gameTime);
                    FishList2[masterIndexFish2].Position += new Vector2(0, 3.5f);
                }
                #endregion

                #region Edge
                if (masterIndexEdge != -1 &&
                    objListEdge[masterIndexEdge] != null)
                    objListEdge[masterIndexEdge].Position += new Vector2(0, 3.5f);
                #endregion
            }
            #region Fish HitTest
            if (masterIndexFish != -1 &&
                    FishList[masterIndexFish] != null)
            {
                if (FishList[masterIndexFish].hitTestObject(Game1.Self.playerRect))
                {
                    Game1.Self.airScale.X = 10f;
                }
                else
                {
                    Game1.Self.airScale.X = 0;
                }
                FishList[masterIndexFish].Position += new Vector2(2.5f, 0);
            }
            if (masterIndexFish2 != -1 &&
                    FishList2[masterIndexFish2] != null)
            {
                if (FishList2[masterIndexFish2].hitTestObject(Game1.Self.playerRect))
                {
                    Game1.Self.airScale.X = 10f;
                }
                else
                {
                    Game1.Self.airScale.X = 0;
                }
                FishList2[masterIndexFish2].Position += new Vector2(-2.5f, 0);
            }
            #endregion
            #endregion
        }

        public void Draw(SpriteBatch spriteBatch, Vector4 RGBA, GameTime gameTime)
        {
            #region Background
            backGround0.ObjectColor = Color.FromNonPremultiplied((int)RGBA.X, (int)RGBA.Y,
                (int)RGBA.Z, (int)RGBA.W);
            backGround1.ObjectColor = Color.FromNonPremultiplied((int)RGBA.X, (int)RGBA.Y,
                (int)RGBA.Z, (int)RGBA.W);

            backGround0.Draw(spriteBatch);
            backGround1.Draw(spriteBatch);
            #endregion

            #region Scenery
            if (masterIndexCenter != -1
                && objListCenter[masterIndexCenter] != null)
                objListCenter[masterIndexCenter].Draw(spriteBatch);
            if (masterIndexEdge != -1
                && objListEdge[masterIndexEdge] != null)
                objListEdge[masterIndexEdge].Draw(spriteBatch);
            if (masterIndexFish != -1
                && FishList[masterIndexFish] != null)
                FishList[masterIndexFish].Draw(gameTime, spriteBatch);
            if (masterIndexFish2 != -1
                && FishList2[masterIndexFish2] != null)
                FishList2[masterIndexFish2].Draw(gameTime, spriteBatch);
            #endregion
        }

        public void RandCenter(Random rand)
        {
            if (masterIndexCenter == -1 || Game1.Self.meters > nextMeterListCenter[masterIndexCenter])
            {
                if (masterIndexCenter == -1 ||
                    objListCenter[masterIndexCenter].Position.Y < 0 - objListCenter[masterIndexCenter].Texture.Height)
                {
                    if (masterIndexCenter == -1 || objListCenter[masterIndexCenter] != null)
                    {
                        #region Higher die Bubble
                        if (Game1.Self.airScale.X < 0.5f)
                        {

                            switch (rand.Next(1, 7))
                            {
                                case 1:
                                    if (lastObjCenter != "centerAlgea")
                                    {
                                        masterIndexCenter++;
                                        nextMeterListCenter.Add(Game1.Self.meters + rand.Next(1, 3));
                                        objListCenter.Add(new CenterAlgea(centerAlgea));
                                        lastObjCenter = "centerAlgea";
                                    }
                                    break;
                                case 2:
                                    if (lastObjCenter != "centerRadio")
                                    {
                                        masterIndexCenter++;
                                        nextMeterListCenter.Add(Game1.Self.meters + rand.Next(1, 3));
                                        objListCenter.Add(new CenterRadio(centerRadio));
                                        lastObjCenter = "centerRadio";
                                    }
                                    break;
                                default:
                                    if (lastObjCenter != "checkpoint")
                                    {
                                        masterIndexCenter++;
                                        nextMeterListCenter.Add(Game1.Self.meters + rand.Next(1, 3));
                                        objListCenter.Add(new AirBubble(airBubble));
                                        lastObjCenter = "checkpoint";
                                    }
                                    break;
                            }
                        }
                        #endregion
                        #region Low die bubble
                        else
                            switch (rand.Next(1, 3))
                            {
                                case 1:
                                    if (lastObjCenter != "centerAlgea")
                                    {
                                        masterIndexCenter++;
                                        nextMeterListCenter.Add(Game1.Self.meters + rand.Next(1, 3));
                                        objListCenter.Add(new CenterAlgea(centerAlgea));
                                        lastObjCenter = "centerAlgea";
                                    }
                                    break;
                                case 2:
                                    if (lastObjCenter != "centerRadio")
                                    {
                                        masterIndexCenter++;
                                        nextMeterListCenter.Add(Game1.Self.meters + rand.Next(1, 3));
                                        objListCenter.Add(new CenterRadio(centerRadio));
                                        lastObjCenter = "centerRadio";
                                    }
                                    break;
                                default:
                                    if (lastObjCenter != "checkpoint")
                                    {
                                        masterIndexCenter++;
                                        nextMeterListCenter.Add(Game1.Self.meters + rand.Next(1, 3));
                                        objListCenter.Add(new AirBubble(airBubble));
                                        lastObjCenter = "checkpoint";
                                    }
                                    break;
                            }
                        #endregion

                        if (objListEdge[masterIndexEdge] != null &&
                            objListEdge[masterIndexEdge].Position.Y < Game1.Self.Window.ClientBounds.Width)
                        {
                            objListCenter[masterIndexCenter].Position = new Vector2(rand.Next(
                                Game1.Self.Window.ClientBounds.Width / 2,
                                Game1.Self.Window.ClientBounds.Width - objListCenter[masterIndexCenter].Texture.Width),
                                Game1.Self.Window.ClientBounds.Height + objListCenter[masterIndexCenter].Texture.Height / 2);
                        }
                        else
                        {
                            objListCenter[masterIndexCenter].Position = new Vector2(rand.Next(
                                   objListCenter[masterIndexCenter].Texture.Width / 2,
                                   Game1.Self.Window.ClientBounds.Width / 2),
                                   Game1.Self.Window.ClientBounds.Height + objListCenter[masterIndexCenter].Texture.Height / 2);
                        }
                    }
                }
            }
            else if (Game1.Self.meters < nextMeterListCenter[masterIndexCenter])
            {
                if (objListCenter[masterIndexCenter].Position.Y - objListCenter[masterIndexCenter].Texture.Height / 2 >
                    Game1.Self.Window.ClientBounds.Height)
                {
                    if (masterIndexCenter > 0)
                        masterIndexCenter--;
                }
            }

        }
        public void RandEdge(Random rand)
        {
            if (masterIndexEdge == -1 || Game1.Self.meters > nextMeterListEdge[masterIndexEdge])
            {
                if (masterIndexEdge == -1 ||
                    objListEdge[masterIndexEdge].Position.Y < 0 - objListEdge[masterIndexEdge].Texture.Height)
                {
                    if (masterIndexEdge == -1 || objListCenter[masterIndexEdge] != null)
                    {
                        switch (rand.Next(1, 2))
                        {
                            #region Switch
                            case 1:
                                if (lastObjEdge != "edgeAlgea")
                                {
                                    masterIndexEdge++;
                                    nextMeterListEdge.Add(Game1.Self.meters + rand.Next(1, 3));
                                    objListEdge.Add(new EdgeAlgea(edgeAlgea));
                                    lastObjEdge = "edgeAlgea";
                                    objListEdge[masterIndexEdge].Position = new Vector2(objListEdge[masterIndexEdge].Position.X,
                                        Game1.Self.Window.ClientBounds.Height + objListEdge[masterIndexEdge].Texture.Height / 2);
                                }
                                break;
                            case 2:
                                if (lastObjEdge != "edgeRadio")
                                {
                                    masterIndexEdge++;
                                    nextMeterListEdge.Add(Game1.Self.meters + rand.Next(1, 3));
                                    objListEdge.Add(new EdgeRadio(edgeRadio));
                                    lastObjEdge = "edgeRadio";
                                    objListEdge[masterIndexEdge].Position = new Vector2(
                                        objListEdge[masterIndexEdge].Texture.Width / 2,
                                        Game1.Self.Window.ClientBounds.Height +
                                        objListEdge[masterIndexEdge].Texture.Height / 2);
                                }
                                break;
                            #endregion
                        }
                    }
                    else if (Game1.Self.meters < nextMeterListEdge[masterIndexEdge])
                    {
                        if (objListCenter[masterIndexCenter].Position.Y - objListCenter[masterIndexEdge].Texture.Height / 2
                            > Game1.Self.Window.ClientBounds.Height)
                        {
                            if (masterIndexEdge > 0)
                                masterIndexEdge--;
                        }
                    }
                }
            }
        }
        public void RandFish(Random rand)
        {
            if (masterIndexFish == -1 ||
                FishList[masterIndexFish].Position.X > Game1.Self.Window.ClientBounds.Width)
            {
                if (masterIndexFish == -1 || FishList[masterIndexFish] != null)
                {
                    if (Game1.Self.meters < 250)
                    {
                        masterIndexFish++;
                        nextFishMeterList.Add(Game1.Self.meters + rand.Next(1, 3));
                        FishList.Add(new Fish(fish0, "fish0"));
                        FishList[masterIndexFish].Position =
                            new Vector2(-FishList[masterIndexFish].Texture.Width,
                            rand.Next(Game1.Self.Window.ClientBounds.Height/3,
                            Game1.Self.Window.ClientBounds.Height));
                        FishList[masterIndexFish].direita = 1;
                    }
                    else if (Game1.Self.meters < 500)
                    {
                        masterIndexFish++;
                        nextFishMeterList.Add(Game1.Self.meters + rand.Next(1, 3));
                        FishList.Add(new Fish(fish1, "fish1"));
                        FishList[masterIndexFish].Position =
                            new Vector2(-FishList[masterIndexFish].Texture.Width,
                            rand.Next(FishList[masterIndexFish].Texture.Height,
                            Game1.Self.Window.ClientBounds.Height));
                        FishList[masterIndexFish].direita = 1;
                    }
                    else if (Game1.Self.meters < 1000)
                    {
                        masterIndexFish++;
                        nextFishMeterList.Add(Game1.Self.meters + rand.Next(1, 3));
                        FishList.Add(new Fish(fish2, "fish2"));
                        FishList[masterIndexFish].Position =
                            new Vector2(-FishList[masterIndexFish].Texture.Width,
                            rand.Next(FishList[masterIndexFish].Texture.Height,
                            Game1.Self.Window.ClientBounds.Height));
                        FishList[masterIndexFish].direita = 1;
                    }
                    else
                    {
                        masterIndexFish++;
                        nextFishMeterList.Add(Game1.Self.meters + rand.Next(1, 3));
                        FishList.Add(new Fish(fish3, "fish3"));
                        FishList[masterIndexFish].Position =
                            new Vector2(-FishList[masterIndexFish].Texture.Width,
                            rand.Next(FishList[masterIndexFish].Texture.Height,
                            Game1.Self.Window.ClientBounds.Height));
                        FishList[masterIndexFish].direita = 1;
                    }
                }
            }
        }
        public void RandFish2(Random rand)
        {
            if (masterIndexFish2 == -1 ||
                FishList2[masterIndexFish2].Position.X < 0)
            {
                if (masterIndexFish2 == -1 || FishList2[masterIndexFish2] != null)
                {
                    if (Game1.Self.meters < 250)
                    {
                        masterIndexFish2++;
                        nextFishMeterList2.Add(Game1.Self.meters + rand.Next(1, 3));
                        FishList2.Add(new Fish(fish0, "fish0"));
                        FishList2[masterIndexFish2].Position =
                            new Vector2(Game1.Self.Window.ClientBounds.Width
                                + FishList2[masterIndexFish2].Texture.Width/2,
                            rand.Next(Game1.Self.Window.ClientBounds.Height/3,
                            Game1.Self.Window.ClientBounds.Height));
                        FishList2[masterIndexFish2].direita = 0;
                    }
                    else if (Game1.Self.meters < 500)
                    {
                        masterIndexFish2++;
                        nextFishMeterList2.Add(Game1.Self.meters + rand.Next(1, 3));
                        FishList2.Add(new Fish(fish1, "fish1"));
                        FishList2[masterIndexFish2].Position =
                            new Vector2(Game1.Self.Window.ClientBounds.Height
                                - FishList2[masterIndexFish2].Texture.Width,
                            rand.Next(FishList2[masterIndexFish2].Texture.Height / 3,
                            Game1.Self.Window.ClientBounds.Height));
                        FishList2[masterIndexFish2].direita = 0;
                    }
                    else if (Game1.Self.meters < 1000)
                    {
                        masterIndexFish2++;
                        nextFishMeterList2.Add(Game1.Self.meters + rand.Next(1, 3));
                        FishList2.Add(new Fish(fish2, "fish2"));
                        FishList2[masterIndexFish2].Position =
                            new Vector2(Game1.Self.Window.ClientBounds.Height 
                                - FishList2[masterIndexFish2].Texture.Width,
                            rand.Next(FishList2[masterIndexFish2].Texture.Height/3,
                            Game1.Self.Window.ClientBounds.Height));
                        FishList2[masterIndexFish2].direita = 0;
                    }
                    else
                    {
                        masterIndexFish2++;
                        nextFishMeterList2.Add(Game1.Self.meters + rand.Next(1, 3));
                        FishList2.Add(new Fish(fish3, "fish3"));
                        FishList2[masterIndexFish2].Position =
                            new Vector2(-FishList2[masterIndexFish2].Texture.Width,
                            rand.Next(FishList2[masterIndexFish2].Texture.Height,
                            Game1.Self.Window.ClientBounds.Height));
                        FishList2[masterIndexFish2].direita = 0;
                    }
                }
            }
        }
    }
    //end class
}